#include <QStringList>
#include <QDebug>
#include <QMutex>
#include "osdremoteservicemodel.h"
#include "../lib/socketsync.h"
#include "../remoteservice/remotedef.h"

#include "../osdglobal.h"
#include "../thread/udpthreadworker.h"
#include <QWaitCondition>
#include <QUdpSocket>
#include <QMetaType>
#include <QStringList>

QMutex g_listen_mutex;

OSDRemoteServiceModel::OSDRemoteServiceModel(QObject *parent) :
    QObject(parent),
    m_worker(NULL)
{

    qRegisterMetaType<BaseResp>("BaseResp");
    qRegisterMetaType<CallInfo>("CallInfo");
    qRegisterMetaType<CameraInfo>("CameraInfo");
    qRegisterMetaType<ConfigInfo>("ConfigInfo");
    qRegisterMetaType<DeviceStatusInfo>("DeviceStatusInfo");
    qRegisterMetaType<MicInfo>("MicInfo");
    qRegisterMetaType<NetworkInfo>("NetworkInfo");
    qRegisterMetaType<NewVersionInfo>("NewVersionInfo");
    qRegisterMetaType<PlatfromStatusInfo>("PlatfromStatusInfo");
    qRegisterMetaType<ProductInfo>("ProductInfo");
    qRegisterMetaType<StatInfo>("StatInfo");
    qRegisterMetaType<SVCStatusInfo>("SVCStatusInfo");
    qRegisterMetaType<SystemStatusInfo>("SystemStatusInfo");
    qRegisterMetaType<SystemTimeInfo>("SystemTimeInfo");
    qRegisterMetaType<ScheduleInfo>("ScheduleInfo");
    m_worker = new UDPThreadWorker;
    m_worker->moveToThread(&m_thread);

    connect(&m_thread, SIGNAL(finished()), m_worker, SLOT(deleteLater()));
    connect(this, SIGNAL(pushMsg(QString, QString)), m_worker, SLOT(sendMsg(QString, QString)));
    connect(m_worker, SIGNAL(response(QString,QString)), this, SLOT(response(QString,QString)));
    connect(m_worker,
            SIGNAL(push(QString)),
            this, SLOT(processPendingDatagram(QString)));
    m_thread.start();
}

void OSDRemoteServiceModel::quit()
{
    m_worker->m_socket->udpsocket()->close();
    m_thread.quit();
    m_thread.wait();
}

OSDRemoteServiceModel &OSDRemoteServiceModel::instance()
{
    static OSDRemoteServiceModel interface;
    return interface;
}

void OSDRemoteServiceModel::processPendingDatagram(QString msg)
{
//    qDebug() << "processPendingDatagram:" << msg;
//    QStringList responseList = msg.split("|");
//    if (msg.size() < 2) {
//        return;
//    }
    QString method = msg;
//    QString data = responseList[1];
    if (method.contains("query_schedule"))
    {
        QStringList responseList = msg.split("|");
        if (responseList.count() < 3) {
            return;
        }
        //日程
        QString data="{\"code\":\"1000\",\"data\":"+responseList[2]+"}";
        dealScheduleList(data);
    } else if (method.contains("onCallConnected")) {
        dealEnterInConf();
    } else if (method.contains("onCallEnd")) {
        dealLeaveConf();
    } else if (method.contains("onProvision"))
    {
        //emit notifyExitApp();
    }
    else if (method.contains("onNetworkChanged"))
    {
        networkStatus();
    }
    else if (method.contains("onPlatformStatusChanged"))
    {
        deviceRegisterStatus();
        deviceUsingStatus();
    }
    else if (method.contains("onSiteCellInfoIndication"))
    {
        QStringList msgList = msg.split("|");
        QString data;
        if (msgList.size() > 1)
        {
            data = msgList[1];
        }
        if (data.size() > 0) {
            updateCellName(data);
        }
    }
}

void OSDRemoteServiceModel::response(QString method, QString r)
{
    if (method.compare(OSD_COMMAND_QUERY_SCHEDULE) == 0)
    {
        ScheduleInfo schedule_info;
        schedule_info.unserialize(r);
        emit notifyScheduleList(schedule_info);
    }
    else if(method.compare(OSD_COMMAND_QUERY_PLATFORM_STATUS) == 0)
    {
        PlatfromStatusInfo pls;
        pls.unserialize(r);
        emit notifyDeviceRegisterStatus(pls);
    }
    else if (method.compare(OSD_COMMAND_QUERY_DEVICE_STATUS) == 0)
    {
        DeviceStatusInfo ds;
        ds.unserialize(r);
        emit notifyDeviceUsingStatus(ds);
    }
    else if (method.compare(OSD_COMMAND_QUERY_SVC_STATUS) == 0)
    {
        SVCStatusInfo svc;
        svc.unserialize(r);
        emit notifySvcRegisterStatus(svc);
    }
    else if (method.compare(OSD_COMMAND_QUERY_SYSTEM_STATUS) == 0)
    {
        SystemStatusInfo sys;
        sys.unserialize(r);
        emit notifySystemStatus(sys);
    }
    else if (method.compare(OSD_COMMAND_QUERY_ENABLE_MIC) == 0)
    {
        MicInfo mic;
        mic.unserialize(r);
        emit notifyMicStatus(mic);
    }
    else if (method.compare(OSD_COMMAND_QUERY_ENABLE_CAMERA) == 0)
    {
        CameraInfo camera;
        camera.unserialize(r);
        emit notifyCameraStatus(camera);
    }
    else if (method.compare(OSD_COMMAND_QUERY_CALL_STATUS) == 0)
    {
        CallInfo call;
        call.unserialize(r);
        emit notifyCallStatus(call);
    }
    else if (method.compare(OSD_COMMAND_QUERY_PRODUCT_INFO) == 0)
    {
        ProductInfo product;
        product.unserialize(r);
        emit notifyProductInfo(product);
    }
    else if (method.compare(OSD_COMMAND_QUERY_NETWORK) == 0)
    {
        NetworkInfo network;
        network.unserialize(r);
        emit notifyNetworkStatus(network);
    }
    else if (method.compare(OSD_COMMAND_QUERY_TIME) == 0)
    {
        SystemTimeInfo systime;
        systime.unserialize(r);
        emit notifySystimeInfo(systime);
    }
    else if (method.compare(OSD_COMMAND_QUERY_CONFIG) == 0)
    {
        ConfigInfo config;
        config.unserialize(r);
        emit notifyConfigInfo(config);
    }
    else if (method.compare(OSD_COMMAND_QUERY_NEW_VERSION) == 0)
    {
        NewVersionInfo v;
        v.unserialize(r);
        emit notifyVersion(v);
    }
    else if (method.compare(OSD_COMMAND_QUERY_STATS) == 0)
    {
        StatInfo si;
        si.unserialize(r);
        emit notifyStats(si);
    }
    else if (method.compare(OSD_COMMAND_REGIST) == 0)
    {
        BaseResp bs;
        bs.unserialize(r);
        emit notifyRegister(bs);
    }
    else if (method.compare(OSD_COMMAND_CALL) == 0)
    {
        BaseResp bs;
        bs.unserialize(r);
        emit notifyCall(bs);
    }
    else if (method.compare(OSD_COMMAND_LEAVE_CONF) == 0)
    {
        BaseResp bs;
        bs.unserialize(r);
        emit notifyLeaveConference(bs);
    }
    else if (method.compare(OSD_COMMAND_SEND_CONTENT) == 0)
    {
        BaseResp bs;
        bs.unserialize(r);
        emit notifySendContent(bs);
    }
    else if (method.compare(OSD_COMMAND_ENABLE_MIC) == 0)
    {
        BaseResp bs;
        bs.unserialize(r);
        emit notifySendMic(bs);
    }
    else if (method.compare(OSD_COMMAND_ENABLE_CAMERA) == 0)
    {
        BaseResp bs;
        bs.unserialize(r);
        emit notifySendCamera(bs);
    }
    else if (method.compare(OSD_COMMAND_MODIFY_NETWORK) == 0)
    {
        BaseResp bs;
        bs.unserialize(r);
        emit notifyModifyNetwork(bs);
    }
    else if (method.compare(OSD_COMMAND_REBOOT) == 0)
    {
        BaseResp bs;
        bs.unserialize(r);
        emit notifyReboot(bs);
    }
    else if (method.compare(OSD_COMMAND_STANDBY) == 0)
    {
        BaseResp bs;
        bs.unserialize(r);
        emit notifyStandby(bs);
    }
    else if (method.contains(OSD_COMMAND_MODIFY_CONFIG))
    {
        QStringList list = method.split("|");
        BaseResp bs;
        if(list.count() > 1)
        {
            bs.setBaseName(list.at(1));
        }
        else
        {
            bs.setBaseName("");
        }
        bs.unserialize(r);
        emit notifyModifyConfig(bs);
    }
    else if (method.compare(OSD_COMMAND_UPGRADE_ONLINE) == 0)
    {
        BaseResp bs;
        bs.unserialize(r);
        emit notifyUpgrade(bs);
    }
}

void OSDRemoteServiceModel::dealLeaveConf()
{
    emit notifyLeaveConf();
}

void OSDRemoteServiceModel::dealEnterInConf()
{
    emit notifyEnterInConf();
}

void OSDRemoteServiceModel::dealScheduleList(QString r)
{
    ScheduleInfo schedule_info;
    schedule_info.unserialize(r);
    emit notifyScheduleList(schedule_info);
}

QString OSDRemoteServiceModel::generateCommand(QString module, QString event, QString data)
{
    QStringList list;
    list << module << event << data;
    return list.join(OSD_COMMAND_SP);
}

void OSDRemoteServiceModel::updateCellName(QString data)
{
    emit notifyUpdateCellName(data);
}

///////////////////////////////////////////////////////////////////////
/// \brief 查询接口
/// \return
///////////////////////////////////////////////////////////////////////
void OSDRemoteServiceModel::deviceRegisterStatus()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_QUERY_PLATFORM_STATUS,"");
    emit pushMsg(OSD_COMMAND_QUERY_PLATFORM_STATUS, msg);
}

void OSDRemoteServiceModel::deviceUsingStatus()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_QUERY_DEVICE_STATUS,"");
    emit pushMsg(OSD_COMMAND_QUERY_DEVICE_STATUS, msg);
}

void OSDRemoteServiceModel::svcRegisterStatus()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_QUERY_SVC_STATUS,"");
    emit pushMsg(OSD_COMMAND_QUERY_SVC_STATUS, msg);
}

void OSDRemoteServiceModel::systemStatus()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_QUERY_SYSTEM_STATUS,"");
    emit pushMsg(OSD_COMMAND_QUERY_SYSTEM_STATUS, msg);
}

void OSDRemoteServiceModel::micStatus()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_QUERY_ENABLE_MIC,"");
    emit pushMsg(OSD_COMMAND_QUERY_ENABLE_MIC, msg);
}

void OSDRemoteServiceModel::cameraStatus()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_QUERY_ENABLE_CAMERA,"");
    emit pushMsg(OSD_COMMAND_QUERY_ENABLE_CAMERA, msg);
}

void OSDRemoteServiceModel::callStatus()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_QUERY_CALL_STATUS,"");
    emit pushMsg(OSD_COMMAND_QUERY_CALL_STATUS, msg);
}

void OSDRemoteServiceModel::productInfo()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_QUERY_PRODUCT_INFO,"");
    emit pushMsg(OSD_COMMAND_QUERY_PRODUCT_INFO, msg);
}

void OSDRemoteServiceModel::networkStatus()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_QUERY_NETWORK,"");
    emit pushMsg(OSD_COMMAND_QUERY_NETWORK, msg);
}

void OSDRemoteServiceModel::systimeInfo()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_QUERY_TIME,"");
    emit pushMsg(OSD_COMMAND_QUERY_TIME, msg);
}

void OSDRemoteServiceModel::config(QString key)
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_QUERY_CONFIG,key);
    emit pushMsg(OSD_COMMAND_QUERY_CONFIG, msg);
}

void OSDRemoteServiceModel::schedules()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_QUERY_SCHEDULE,"");
    emit pushMsg(OSD_COMMAND_QUERY_SCHEDULE,msg);
}

void OSDRemoteServiceModel::version()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_QUERY_NEW_VERSION,"");
    emit pushMsg(OSD_COMMAND_QUERY_NEW_VERSION,msg);
}

void OSDRemoteServiceModel::stats()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_QUERY_STATS,"");
    emit pushMsg(OSD_COMMAND_QUERY_STATS,msg);
}

///////////////////////////////////////////////////////////////////////////////////
/// \brief 操作接口
/// \return
///////////////////////////////////////////////////////////////////////////////////

void OSDRemoteServiceModel::registerDevice()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_REGIST,"");
    emit pushMsg(OSD_COMMAND_REGIST,msg);
}

void OSDRemoteServiceModel::call(QString number, QString pwd, QString name)
{
    OSDJson json;
    json.insert("conference_number", number);
    json.insert("display_name", name);
    json.insert("password", pwd);
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_CALL,QString(json.str()));
    emit pushMsg(OSD_COMMAND_CALL,msg);
}

void OSDRemoteServiceModel::leaveConference()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_LEAVE_CONF,"");
    emit pushMsg(OSD_COMMAND_LEAVE_CONF,msg);
}

void OSDRemoteServiceModel::sendContent(bool enable)
{
    OSDJson json;
    int vstr = enable ? 1:0;
    json.insert("enable",vstr);
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_SEND_CONTENT,QString(json.str()));
    emit pushMsg(OSD_COMMAND_SEND_CONTENT,msg);
}

void OSDRemoteServiceModel::sendMic(bool enable)
{
    OSDJson json;
    int vstr = enable ? 1:0;
    json.insert("enable",vstr);
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_ENABLE_MIC,QString(json.str()));
    emit pushMsg(OSD_COMMAND_ENABLE_MIC,msg);
}

void OSDRemoteServiceModel::sendCamera(bool enable)
{
    OSDJson json;
    int vstr = enable ? 1:0;
    json.insert("enable",vstr);
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_ENABLE_CAMERA,QString(json.str()));
    emit pushMsg(OSD_COMMAND_ENABLE_CAMERA,msg);
}

void OSDRemoteServiceModel::modifyNetwork(QString ip, QString mask, QString gateway, QString dns)
{
    OSDJson json;
    json.insert("ip", ip);
    json.insert("mask", mask);
    json.insert("gateway", gateway);
    json.insert("dns", dns);
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_MODIFY_NETWORK,QString(json.str()));
    emit pushMsg(OSD_COMMAND_MODIFY_NETWORK,msg);
}

void OSDRemoteServiceModel::reboot()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_REBOOT,"");
    emit pushMsg(OSD_COMMAND_REBOOT,msg);
}

void OSDRemoteServiceModel::standby()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_STANDBY,"");
    emit pushMsg(OSD_COMMAND_STANDBY,msg);
}

void OSDRemoteServiceModel::recover()
{
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_RECOVER,"");
    emit pushMsg(OSD_COMMAND_RECOVER,msg);
}

void OSDRemoteServiceModel::modifyConfig(QString key, QVariant v)
{
    OSDJson json;
    json.insert("key", key);
    json.insert("value", v);
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_MODIFY_CONFIG,QString(json.str()));
    emit pushMsg(OSD_COMMAND_MODIFY_CONFIG+QString("|")+key,msg);
}

void OSDRemoteServiceModel::upgrade()
{
    QString arg = "latest";
    QString msg = generateCommand(OSD_MODULE_NAME,OSD_COMMAND_UPGRADE_ONLINE,arg);
    emit pushMsg(OSD_COMMAND_UPGRADE_ONLINE,msg);
}
